package main

import (
	"database/sql"
	"errors"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"log"
	"os"
)

func main() {
	defer func() {
		if p := recover(); p != nil {
			err := fmt.Errorf("internal error: %v", p)
			errprint(err)
		}
	}()

	os.Remove("./foo.db")

	db, err := sql.Open("sqlite3", "./foo.db")      ;errlog(err)

	defer db.Close()

	sqlStmt := `
	create table foo (id integer not null primary key, name text);
	delete from foo;
	`
	_, err = db.Exec(sqlStmt)
	if err != nil {		log.Printf("%q: %s\n", err, sqlStmt)	;	return	}

	tx, err := db.Begin()                                                      ;errlog(err)
	stmt, err := tx.Prepare("insert into foo(id, name) values(?, ?)")    ;errlog(err)
	defer stmt.Close()
	for i := 0; i < 10; i++ {
		res, err := stmt.Exec(i, fmt.Sprintf("测试sqlite%03d", i))    ;errlog(err)
		id, err := res.LastInsertId()
		fmt.Println(id)
	}
	tx.Commit()

	rows, err := db.Query("select id, name from foo where name like '测试%'")      ;errlog(err)
	defer rows.Close()
	for rows.Next() {
		var id int
		var name string
		err = rows.Scan(&id, &name)    ;errlog(err)
		fmt.Println(id, name)
	}
	err = rows.Err()                   ;errlog(err)

	stmt, err = db.Prepare("select name from foo where id = ?")    ;errlog(err)
	defer stmt.Close()
	var name string
	err = stmt.QueryRow("3").Scan(&name)    ;errlog(err)
	fmt.Println(name)

	res, err := db.Exec("delete from foo")    ;errlog(err)
	affect, err := res.RowsAffected()
	fmt.Println(affect)

	_, err = db.Exec("insert into foo(id, name) values(1, 'foo'), (2, 'bar'), (3, 'baz')")    ;errlog(err)

	rows, err = db.Query("select id, name from foo")   	;errlog(err)
	defer rows.Close()
	for rows.Next() {
		var id int
		var name string
		err = rows.Scan(&id, &name)     ;	errlog(err)
		fmt.Println(id, name)
	}
	err = rows.Err()
	errlog(err)

	// 模拟一个错误，触发之 。被匿名函数捕获：从error 中恢复，并打印
	var EOF = errors.New("EOF")
	panic(EOF )

}
func errlog(e error,v ...interface{})  {
	if e != nil{
		log.Fatal(e,">>",v)
	}
}
func errprint(e error,v ...interface{})  {
	if e != nil{
		fmt.Println(e,">>",v)
	}
}
// sqlite3  不支持 regexp ，模糊查询用like